import { calculateX, calculateY } from '../composables/useConvertMap';
import { useTooltipInjector } from '../composables/useTooltip';
import {
  computed,
  defineComponent,
  h,
  PropType,
  VNodeArrayChildren,
} from 'vue';
import ferryIcon from '../assets/images/ferry.png';
import destIcon from '../assets/images/chart-icon5.png';

const SH_COORDS = [121.47, 31];
type CoordsType = {
  name: string;
  coords: number[];
};
export default defineComponent({
  name: 'OceanPath',
  props: {
    coordinates: {
      type: Array as PropType<Array<CoordsType>>,
      default: () => [
        { coords: SH_COORDS, name: '' },
        { coords: [180, 180], name: '' },
      ],
    },
    strokeWidth: {
      type: [Number, String],
      default: 0.4,
    },
    rotateY: Boolean,
    noDest: Boolean,
  },
  setup(props) {
    const { state: tooltipState } = useTooltipInjector();
    const computedPath = computed(() => {
      const coords = props.coordinates;
      let c = coords[0].coords,
        c1 = calculateX(c[0]),
        c2 = calculateY(c[1]),
        str = `M ${c1} ${c2} `;
      let reverse = `, ${c1} ${c2}`;

      for (let i = 1; i < coords.length; i++) {
        c = coords[i].coords;
        c1 = calculateX(c[0] || 0);
        c2 = calculateY(c[1] || 0);
        if (i % 2 !== 0) {
          str += `Q ${c1} ${c2}, `;
          reverse = `Q ${c1} ${c2}` + reverse;
        } else {
          str += `${c1} ${c2}`;
          if (i === coords.length - 1) {
            reverse = `M ${c1} ${c2}` + reverse;
          } else {
            reverse = `, ${c1} ${c2}` + reverse;
          }
        }
      }
      str += reverse;
      return str;
    });

    return {
      computedPath,
      tooltipState,
    };
  },
  data() {
    return {
      timer: 0 as any,
      interval: 25,
      way: !!this.rotateY,
    };
  },
  mounted() {
    this.timer = setInterval(() => {
      this.way = !this.way;
    }, this.interval * 1000);
  },
  beforeUnmount() {
    clearInterval(this.timer);
    this.timer = 0;
  },
  methods: {
    genIcon() {
      const rotateY = this.way ? 'rotateY(180deg)' : '';
      return h(
        'image',
        {
          width: '6px',
          height: '6px',
          'xlink:href': ferryIcon,
          style: {
            transform: 'rotateX(180deg) ' + rotateY + ' translate(-3px, -3px)',
          },
        },
        this.genAnimate()
      );
    },
    genPath() {
      return h('path', {
        d: this.computedPath,
        class: 'f-dest--icon',
        stroke: 'var(--light-yellow)',
        'stroke-width': +this.strokeWidth,
        fill: 'transparent',
        'stroke-dasharray': '1',
        opacity: 0.6,
      });
    },
    genAnimate() {
      return h('animateMotion', {
        path: this.computedPath,
        dur: this.interval * 2 + 's',
        repeatCount: 'indefinite',
        // rotate: 'auto',
      });
    },
    onMouseleave() {
      this.tooltipState.showTooltip = false;
    },
    genDest(c: CoordsType, key = '') {
      if (!c.name) return;
      return h('image', {
        'xlink:href': destIcon,
        width: '4px',
        height: '4px',
        key: key,
        class: 'f-dest--icon',
        x: calculateX(c.coords[0]),
        y: calculateY(c.coords[1]),
        style: {
          transform: 'translate(-2px, -2px)',
          'z-index': '2',
          cursor: 'pointer',
        },
        onMouseenter: ($event: MouseEvent) => {
          this.tooltipState.showTooltip = true;
          this.tooltipState.text = c.name || '';
          this.tooltipState.clientX = $event.clientX;
          this.tooltipState.clientY = $event.clientY;
        },
        onMouseleave: this.onMouseleave,
      });
    },
    genDests() {
      const children: VNodeArrayChildren = [];
      let c;
      for (let i = 1; i < this.coordinates.length; i++) {
        c = this.coordinates[i];
        if (!c.name) continue;
        children.push(this.genDest(c, 'dest-' + i));
      }
      return children;
    },
  },
  render() {
    return h('g', {}, [this.genIcon(), this.genPath(), ...this.genDests()]);
  },
});
